package com.kwdb.importtool.ui;

import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.*;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 拖拽面板
 * 支持拖拽SQL文件到面板进行迁移操作
 */
@Data
public class DragDropPanel extends JPanel implements DropTargetListener {
    private static final Logger logger = LoggerFactory.getLogger(DragDropPanel.class);

    // UI组件
    private JLabel titleLabel;
    private JLabel iconLabel;
    private JLabel instructionLabel;
    private JLabel fileInfoLabel;
    private JButton browseButton;
    private JButton clearButton;
    private JProgressBar progressBar;

    // 文件相关
    private File droppedFile;
    private List<FileDropListener> dropListeners;

    // 状态
    private boolean dragOver;
    private boolean fileLoaded;

    // 常量
    private static final Color NORMAL_BACKGROUND = new Color(240, 240, 240);
    private static final Color DRAG_OVER_BACKGROUND = new Color(220, 240, 255);
    private static final Color LOADED_BACKGROUND = new Color(220, 255, 220);
    private static final int PANEL_WIDTH = 400;
    private static final int PANEL_HEIGHT = 300;

    public DragDropPanel() {
        this.dropListeners = new ArrayList<>();
        this.dragOver = false;
        this.fileLoaded = false;

        initializeUI();
        setupDropTarget();
    }

    /**
     * 初始化用户界面
     */
    private void initializeUI() {
        setLayout(new BorderLayout(10, 10));
        setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
        setBackground(NORMAL_BACKGROUND);
        setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(Color.GRAY, 2, true),
                BorderFactory.createEmptyBorder(20, 20, 20, 20)
        ));

        // 创建主面板
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
        mainPanel.setOpaque(false);

        // 标题
        titleLabel = new JLabel("MySQL to KWDB 迁移工具", JLabel.CENTER);
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
        titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        // 图标
        iconLabel = new JLabel("📁", JLabel.CENTER);
        iconLabel.setFont(new Font("Segoe UI Emoji", Font.PLAIN, 48));
        iconLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        // 说明文本
        instructionLabel = new JLabel("<html><center>拖拽 MySQL SQL 文件到此区域<br/>或点击下方按钮选择文件</center></html>", JLabel.CENTER);
        instructionLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        instructionLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        // 文件信息标签
        fileInfoLabel = new JLabel(" ", JLabel.CENTER);
        fileInfoLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 10));
        fileInfoLabel.setForeground(Color.DARK_GRAY);
        fileInfoLabel.setAlignmentX(Component.CENTER_ALIGNMENT);

        // 进度条
        progressBar = new JProgressBar(0, 100);
        progressBar.setPreferredSize(new Dimension(300, 20));
        progressBar.setStringPainted(true);
        progressBar.setVisible(false);
        progressBar.setAlignmentX(Component.CENTER_ALIGNMENT);

        // 按钮面板
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 0));
        buttonPanel.setOpaque(false);

        browseButton = new JButton("选择文件");
        browseButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        browseButton.addActionListener(e -> browseForFile());

        clearButton = new JButton("清除");
        clearButton.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        clearButton.setEnabled(false);
        clearButton.addActionListener(e -> clearFile());

        buttonPanel.add(browseButton);
        buttonPanel.add(clearButton);

        // 添加组件到主面板
        mainPanel.add(Box.createVerticalGlue());
        mainPanel.add(titleLabel);
        mainPanel.add(Box.createRigidArea(new Dimension(0, 10)));
        mainPanel.add(iconLabel);
        mainPanel.add(Box.createRigidArea(new Dimension(0, 20)));
        mainPanel.add(instructionLabel);
        mainPanel.add(Box.createRigidArea(new Dimension(0, 10)));
        mainPanel.add(fileInfoLabel);
        mainPanel.add(Box.createRigidArea(new Dimension(0, 20)));
        mainPanel.add(progressBar);
        mainPanel.add(Box.createRigidArea(new Dimension(0, 10)));
        mainPanel.add(buttonPanel);
        mainPanel.add(Box.createVerticalGlue());

        add(mainPanel, BorderLayout.CENTER);

        // 添加鼠标悬停效果
        addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                if (!dragOver && !fileLoaded) {
                    setBackground(DRAG_OVER_BACKGROUND);
                }
            }

            public void mouseExited(java.awt.event.MouseEvent evt) {
                if (!dragOver && !fileLoaded) {
                    setBackground(NORMAL_BACKGROUND);
                }
            }
        });
    }

    /**
     * 设置拖拽目标
     */
    private void setupDropTarget() {
        new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true);
    }

    /**
     * 浏览选择文件
     */
    private void browseForFile() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("选择 MySQL SQL 文件");
        fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

        // 设置文件过滤器
        fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {
            @Override
            public boolean accept(File file) {
                if (file.isDirectory()) {
                    return true;
                }
                String filename = file.getName().toLowerCase();
                return filename.endsWith(".sql") || filename.endsWith(".txt");
            }

            @Override
            public String getDescription() {
                return "SQL文件 (*.sql, *.txt)";
            }
        });

        int result = fileChooser.showOpenDialog(this);
        if (result == JFileChooser.APPROVE_OPTION) {
            File selectedFile = fileChooser.getSelectedFile();
            handleDroppedFile(selectedFile);
        }
    }

    /**
     * 清除已选择的文件
     */
    private void clearFile() {
        droppedFile = null;
        fileLoaded = false;
        clearButton.setEnabled(false);
        progressBar.setVisible(false);

        setBackground(NORMAL_BACKGROUND);
        fileInfoLabel.setText(" ");
        instructionLabel.setText("<html><center>拖拽 MySQL SQL 文件到此区域<br/>或点击下方按钮选择文件</center></html>");
        iconLabel.setText("📁");

        // 通知监听器
        fireFileCleared();
    }

    /**
     * 处理拖拽的文件
     */
    public void handleDroppedFile(File file) {
        if (file == null || !file.exists()) {
            showError("文件不存在");
            return;
        }

        if (!file.isFile()) {
            showError("请选择文件而不是目录");
            return;
        }

        if (!isValidSQLFile(file)) {
            showError("请选择有效的SQL文件（.sql扩展名）");
            return;
        }

        if (file.length() == 0) {
            showError("文件为空");
            return;
        }

        // 文件大小检查（100MB限制）
//        long maxSize = 100 * 1024 * 1024; // 100MB
        long maxSize = 3L * 1024 * 1024 * 1024; // 3GB
        if (file.length() > maxSize) {
/*            int result = JOptionPane.showConfirmDialog(this,
                    "文件较大（" + formatFileSize(file.length()) + "），可能处理时间较长，是否继续？",
                    "文件较大确认", JOptionPane.YES_NO_OPTION);

            if (result != JOptionPane.YES_OPTION) {
                return;
            }*/
            JOptionPane.showMessageDialog(this,
                    "文件较大（" + formatFileSize(file.length()) + "），可能处理时间较长，请拆分后处理。");
            return;
        }

        // 设置文件状态
        droppedFile = file;
        fileLoaded = true;
        clearButton.setEnabled(true);

        setBackground(LOADED_BACKGROUND);
        updateFileInfo();

        // 通知监听器
        fireFileDropped(file);
    }

    /**
     * 验证是否为有效的SQL文件
     */
    private boolean isValidSQLFile(File file) {
        String fileName = file.getName().toLowerCase();
        return fileName.endsWith(".sql");
    }

    /**
     * 更新文件信息显示
     */
    private void updateFileInfo() {
        if (droppedFile != null) {
            String fileName = droppedFile.getName();
            String fileSize = formatFileSize(droppedFile.length());
            String filePath = droppedFile.getParent();

            // 缩短路径显示
            if (filePath != null && filePath.length() > 30) {
                filePath = "..." + filePath.substring(filePath.length() - 27);
            }

            fileInfoLabel.setText("<html><b>" + fileName + "</b> (" + fileSize + ")<br>" + filePath + "</html>");
            instructionLabel.setText("<html><center>文件已加载<br/>准备开始迁移</center></html>");
            iconLabel.setText("✅");
        }
    }

    /**
     * 格式化文件大小
     */
    private static String formatFileSize(long size) {
        if (size < 1024) {
            return size + " B";
        } else if (size < 1024 * 1024) {
            return String.format("%.1f KB", size / 1024.0);
        } else if (size < 1024 * 1024 * 1024) {
            return String.format("%.1f MB", size / (1024.0 * 1024.0));
        } else {
            return String.format("%.1f GB", size / (1024.0 * 1024.0 * 1024.0));
        }
    }

    /**
     * 显示错误消息
     */
    private void showError(String message) {
        JOptionPane.showMessageDialog(this, message, "错误", JOptionPane.ERROR_MESSAGE);
    }

    /**
     * 设置进度
     */
    public void setProgress(int progress, String message) {
        SwingUtilities.invokeLater(() -> {
            progressBar.setVisible(true);
            progressBar.setValue(progress);
            progressBar.setString(message);

            if (progress >= 100) {
                // 迁移完成，几秒后隐藏进度条
                new Timer(3000, e -> {
                    progressBar.setVisible(false);
                    ((Timer) e.getSource()).stop();
                }).start();
            }
        });
    }

    /**
     * 显示加载状态
     */
    public void showLoading(boolean loading) {
        SwingUtilities.invokeLater(() -> {
            if (loading) {
                iconLabel.setText("⏳");
                instructionLabel.setText("<html><center>处理中...</center></html>");
                browseButton.setEnabled(false);
                clearButton.setEnabled(false);
            } else {
                iconLabel.setText("✅");
                instructionLabel.setText("<html><center>文件已加载<br/>准备开始迁移</center></html>");
                browseButton.setEnabled(true);
                clearButton.setEnabled(true);
            }
        });
    }

    // DropTargetListener 接口实现

    @Override
    public void dragEnter(DropTargetDragEvent dtde) {
        dragOver = true;
        setBackground(DRAG_OVER_BACKGROUND);
        dtde.acceptDrag(DnDConstants.ACTION_COPY);
    }

    @Override
    public void dragOver(DropTargetDragEvent dtde) {
        // 保持拖拽状态
    }

    @Override
    public void dropActionChanged(DropTargetDragEvent dtde) {
        // 不需要处理
    }

    @Override
    public void dragExit(DropTargetEvent dte) {
        dragOver = false;
        if (!fileLoaded) {
            setBackground(NORMAL_BACKGROUND);
        }
    }

    @Override
    public void drop(DropTargetDropEvent dtde) {
        dragOver = false;

        try {
            dtde.acceptDrop(DnDConstants.ACTION_COPY);

            java.awt.datatransfer.Transferable transferable = dtde.getTransferable();
            if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
                @SuppressWarnings("unchecked")
                java.util.List<File> fileList = (java.util.List<File>)
                        transferable.getTransferData(DataFlavor.javaFileListFlavor);

                if (fileList != null && !fileList.isEmpty()) {
                    // 只处理第一个文件
                    File file = fileList.get(0);
                    handleDroppedFile(file);
                    dtde.dropComplete(true);
                    return;
                }
            }

            dtde.dropComplete(false);

        } catch (Exception ex) {
            logger.error("文件拖拽处理失败", ex);
            dtde.dropComplete(false);
            showError("文件处理失败: " + ex.getMessage());
        } finally {
            if (!fileLoaded) {
                setBackground(NORMAL_BACKGROUND);
            }
        }
    }

    // 事件监听器支持

    /**
     * 添加文件拖拽监听器
     */
    public void addFileDropListener(FileDropListener listener) {
        dropListeners.add(listener);
    }

    /**
     * 移除文件拖拽监听器
     */
    public void removeFileDropListener(FileDropListener listener) {
        dropListeners.remove(listener);
    }

    /**
     * 触发文件拖拽事件
     */
    private void fireFileDropped(File file) {
        for (FileDropListener listener : dropListeners) {
            listener.onFileDropped(file);
        }
    }

    /**
     * 触发文件清除事件
     */
    private void fireFileCleared() {
        for (FileDropListener listener : dropListeners) {
            listener.onFileCleared();
        }
    }

    // 公共方法

    public File getDroppedFile() {
        return droppedFile;
    }

    public boolean isFileLoaded() {
        return fileLoaded;
    }

    public void reset() {
        clearFile();
        setProgress(0, "准备就绪");
    }

    /**
     * 文件拖拽监听器接口
     */
    public interface FileDropListener {
        void onFileDropped(File file);
        void onFileCleared();
    }

    /**
     * 文件信息类
     */
    @Data
    public static class FileInfo {
        private String fileName;
        private long fileSize;
        private String filePath;
        private Date dropTime;

        public FileInfo(File file) {
            this.fileName = file.getName();
            this.fileSize = file.length();
            this.filePath = file.getAbsolutePath();
            this.dropTime = new Date();
        }

        public String getFormattedSize() {
            return formatFileSize(fileSize);
        }
    }

    // 测试主方法
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("拖拽面板测试");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            DragDropPanel panel = new DragDropPanel();
            panel.addFileDropListener(new FileDropListener() {
                @Override
                public void onFileDropped(File file) {
                    System.out.println("文件拖拽: " + file.getAbsolutePath());
                }

                @Override
                public void onFileCleared() {
                    System.out.println("文件已清除");
                }
            });

            frame.getContentPane().add(panel);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}